package com.wuyou.securitydemo.component;

import com.wuyou.sso.common.excption.CustomException;
import com.wuyou.securitydemo.config.AuthConfig;
import com.wuyou.securitydemo.domain.TokenVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.UUID;

@Component
public class CustomizedTokenService {

    @Autowired
    private CustomizedRedisTokenStore tokenStore;
    @Autowired
    private CustomizedTokenEnhancer enhancer;
    @Autowired
    private AuthConfig authConfig;

    public TokenVO createToken(Authentication authentication){
        TokenVO existingToken = tokenStore.getToken(authentication);
        if (existingToken != null) {
            // 允许重用令牌的情况下，直接发放已经存在的令牌
//            if (authConfig.getAllowReuseAccessToken()) {
//                 Re-store the access token in case the authentication has changed
//                tokenStore.store(existingToken, authentication);
//            }else {
//                 提出原有令牌，重新生成新令牌
//                TokenVO token = createNewToken(authentication);
//                tokenStore.store(token, authentication);
//                return token;
//            }
            return existingToken;
        }else {
            TokenVO token = createNewToken(authentication);
            tokenStore.store(token, authentication);
            return token;
        }
    }

    private TokenVO createNewToken(Authentication authentication){
        TokenVO tokenVO = new TokenVO();
        tokenVO.setToken(UUID.randomUUID().toString());
        tokenVO.setAdditional(Collections.EMPTY_MAP);
        tokenVO.setTokenType("Bearer".toLowerCase());
        return enhancer.enhance(tokenVO, authentication);
    }

    public Authentication loadAuthentication(String token) throws AuthenticationException {
        TokenVO tokenVO = tokenStore.readAccessToken(token);
        if (tokenVO == null) {
            throw new CustomException("Invalid access token: " + token);
        } else if (!tokenVO.isActive()) {
            tokenStore.remove(token);
            throw new CustomException("Access token expired: " + token);
        }

        Authentication result = tokenStore.readAuthentication(token);
        if (result == null) {
            // in case of race condition
            throw new CustomException("Invalid access token: " + token);
        }
        return result;
    }

    public void destroy(String token) {
        tokenStore.remove(token);
    }
}